package com.sys.app.entity.util;

import com.sys.app.entity.sys.SysMenu;
import com.sys.app.entity.sys.TreeNode;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;
public class TreeUtil {
    /**
     * 获取所有的根节点
     */
//    public static <T extends TreeNode> List<T> getRootNode(List<T> treeNodeList, Set<Long> nodeIdSet){
//        List<T> rootNodeList = new ArrayList<>();
//        for (T treeNode : treeNodeList) {
//            if (treeNode.getParentId().equals(0L)|| null == treeNode.getParentId()){
//                rootNodeList.add(treeNode);
//                nodeIdSet.add(treeNode.getId());
//            }
//        }
//        return rootNodeList;
//    }

    /**
     * 构建树
     */
//    public static <T extends TreeNode> T buildChildTree(T rootNode,List<T> treeNodeList,Set<Long> nodeIdSet){
//        List<T> childNodeList = new ArrayList<>();
//        for (T treeNode : treeNodeList) {
//            if (!nodeIdSet.contains(treeNode.getId()) && treeNode.getParentId().equals(rootNode.getId())){
//                nodeIdSet.add(treeNode.getId());
//                //这里相当于把当前节点又作为父节点 递归查询子节点
//                childNodeList.add(buildChildTree(treeNode,treeNodeList,nodeIdSet));
//            }
//        }
//        rootNode.setChildren((List<TreeNode>) childNodeList);
//        return rootNode;
//    }
//    public static <T extends TreeNode> List<T> buildTree(List<T> treeNodeList){
//        if (CollectionUtils.isEmpty(treeNodeList)){
//            return Collections.emptyList();
//        }
//        //用来保存每一棵完整的树
//        List<T> treeNodes = new ArrayList<T>();
//        //用来保存已装填过的树节点ID 防止重复遍历
//        Set<Long> nodeIdSet = new HashSet<>();
//        for (T root : getRootNode(treeNodeList,nodeIdSet)) {
//            T treeNode = buildChildTree(root, treeNodeList,nodeIdSet);
//            treeNodes.add(treeNode);
//        }
//        return treeNodes;
//    }


    //----------------------------------------非递归树---------------------
    public static <T extends TreeNode> List<T> buildTreeTwo(List<T> treeNodeList){
        List<T> rootNodeList = new ArrayList<>();
        //移除根数据
        rootNodeList = treeNodeList.stream().filter(d -> d.getParentId()==null || d.getParentId().equals(0L)).collect(Collectors.toList());
        treeNodeList.removeAll(rootNodeList);
        //根据父节点分组
        Map<Long, List<T>> childMap = treeNodeList.stream().collect(Collectors.groupingBy(T::getParentId));
        //设置子节点[这里不包括根节点]
        treeNodeList.forEach(treeNode -> treeNode.setChildren(castList(childMap.get(treeNode.getId()),TreeNode.class)));
        //将上面已经构建的子树拼到对应的根节点上
        return rootNodeList.stream().peek(root -> root.setChildren(castList(childMap.get(root.getId()),TreeNode.class))).collect(Collectors.toList());
    }

    //获取菜单列表数据
    public static <T extends SysMenu> List<T> buildTree(List<T> treeNodeList){
        List<T> rootNodeList = new ArrayList<>();
        //移除根数据
        rootNodeList = treeNodeList.stream().filter(d -> d.getPid()==null || d.getPid().equals(0L)).collect(Collectors.toList());
        treeNodeList.removeAll(rootNodeList);
        //根据父节点分组
        Map<Long, List<T>> childMap = treeNodeList.stream().collect(Collectors.groupingBy(T::getPid));
        //设置子节点[这里不包括根节点]
        treeNodeList.forEach(treeNode -> treeNode.setChildren(castList(childMap.get(treeNode.getId()),SysMenu.class)));
        //将上面已经构建的子树拼到对应的根节点上
        return rootNodeList.stream().peek(root -> root.setChildren(castList(childMap.get(root.getId()),SysMenu.class))).collect(Collectors.toList());
    }



    private static <T> List<T> castList(Object obj, Class<T> clazz)
    {
        List<T> result = new ArrayList<T>();
        if(obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }
}
